home *** CD-ROM | disk | FTP | other *** search
Wrap
# Source Generated with Decompyle++ # File: in.pyc (Python 2.4) import os import sys import socket import string import re import select import errno import nmb import types from random import randint from struct import * import ntlm from dcerpc import samr from structure import Structure unicode_support = 0 unicode_convert = 1 try: from cStringIO import StringIO except ImportError: from StringIO import StringIO from binascii import a2b_hex CVS_REVISION = '$Revision: 1.7 $' SHARED_DISK = 0 SHARED_PRINT_QUEUE = 1 SHARED_DEVICE = 2 SHARED_IPC = 3 ATTR_ARCHIVE = 32 ATTR_COMPRESSED = 2048 ATTR_NORMAL = 128 ATTR_HIDDEN = 2 ATTR_READONLY = 1 ATTR_TEMPORARY = 256 ATTR_DIRECTORY = 16 ATTR_SYSTEM = 4 SERVICE_DISK = 'A:' SERVICE_PRINTER = 'LPT1:' SERVICE_IPC = 'IPC' SERVICE_COMM = 'COMM' SERVICE_ANY = '?????' SV_TYPE_WORKSTATION = 1 SV_TYPE_SERVER = 2 SV_TYPE_SQLSERVER = 4 SV_TYPE_DOMAIN_CTRL = 8 SV_TYPE_DOMAIN_BAKCTRL = 16 SV_TYPE_TIME_SOURCE = 32 SV_TYPE_AFP = 64 SV_TYPE_NOVELL = 128 SV_TYPE_DOMAIN_MEMBER = 256 SV_TYPE_PRINTQ_SERVER = 512 SV_TYPE_DIALIN_SERVER = 1024 SV_TYPE_XENIX_SERVER = 2048 SV_TYPE_NT = 4096 SV_TYPE_WFW = 8192 SV_TYPE_SERVER_NT = 16384 SV_TYPE_POTENTIAL_BROWSER = 65536 SV_TYPE_BACKUP_BROWSER = 131072 SV_TYPE_MASTER_BROWSER = 262144 SV_TYPE_DOMAIN_MASTER = 524288 SV_TYPE_LOCAL_LIST_ONLY = 1073741824 SV_TYPE_DOMAIN_ENUM = 0x80000000L SMB_O_CREAT = 16 SMB_O_EXCL = 0 SMB_O_OPEN = 1 SMB_O_TRUNC = 2 SMB_SHARE_COMPAT = 0 SMB_SHARE_DENY_EXCL = 16 SMB_SHARE_DENY_WRITE = 32 SMB_SHARE_DENY_READEXEC = 48 SMB_SHARE_DENY_NONE = 64 SMB_ACCESS_READ = 0 SMB_ACCESS_WRITE = 1 SMB_ACCESS_READWRITE = 2 SMB_ACCESS_EXEC = 3 TRANS_DISCONNECT_TID = 1 TRANS_NO_RESPONSE = 2 def set_key_odd_parity(key): '' for i in range(len(key)): for k in range(7): bit = 0 t = key[i] >> k bit = (t ^ bit) & 1 key[i] = key[i] & 254 | bit return key def strerror(errclass, errcode): if errclass == 1: return ('OS error', ERRDOS.get(errcode, 'Unknown error')) elif errclass == 2: return ('Server error', ERRSRV.get(errcode, 'Unknown error')) elif errclass == 3: return ('Hardware error', ERRHRD.get(errcode, 'Unknown error')) elif errclass == 128: return ('Browse error', ERRBROWSE.get(errcode, 'Unknown error')) elif errclass == 255: return ('Bad command', 'Bad command. Please file bug report') else: return ('Unknown error', 'Unknown error') class SessionError(Exception): ERRsuccess = 0 ERRbadfunc = 1 ERRbadfile = 2 ERRbadpath = 3 ERRnofids = 4 ERRnoaccess = 5 ERRbadfid = 6 ERRbadmcb = 7 ERRnomem = 8 ERRbadmem = 9 ERRbadenv = 10 ERRbadaccess = 12 ERRbaddata = 13 ERRres = 14 ERRbaddrive = 15 ERRremcd = 16 ERRdiffdevice = 17 ERRnofiles = 18 ERRgeneral = 31 ERRbadshare = 32 ERRlock = 33 ERRunsup = 50 ERRnetnamedel = 64 ERRnosuchshare = 67 ERRfilexists = 80 ERRinvalidparam = 87 ERRcannotopen = 110 ERRinsufficientbuffer = 122 ERRinvalidname = 123 ERRunknownlevel = 124 ERRnotlocked = 158 ERRrename = 183 ERRbadpipe = 230 ERRpipebusy = 231 ERRpipeclosing = 232 ERRnotconnected = 233 ERRmoredata = 234 ERRnomoreitems = 259 ERRbaddirectory = 267 ERReasnotsupported = 282 ERRlogonfailure = 1326 ERRbuftoosmall = 2123 ERRunknownipc = 2142 ERRnosuchprintjob = 2151 ERRinvgroup = 2455 ERRnoipc = 66 ERRdriveralreadyinstalled = 1795 ERRunknownprinterport = 1796 ERRunknownprinterdriver = 1797 ERRunknownprintprocessor = 1798 ERRinvalidseparatorfile = 1799 ERRinvalidjobpriority = 1800 ERRinvalidprintername = 1801 ERRprinteralreadyexists = 1802 ERRinvalidprintercommand = 1803 ERRinvaliddatatype = 1804 ERRinvalidenvironment = 1805 ERRunknownprintmonitor = 3000 ERRprinterdriverinuse = 3001 ERRspoolfilenotfound = 3002 ERRnostartdoc = 3003 ERRnoaddjob = 3004 ERRprintprocessoralreadyinstalled = 3005 ERRprintmonitoralreadyinstalled = 3006 ERRinvalidprintmonitor = 3007 ERRprintmonitorinuse = 3008 ERRprinterhasjobsqueued = 3009 ERRerror = 1 ERRbadpw = 2 ERRbadtype = 3 ERRaccess = 4 ERRinvnid = 5 ERRinvnetname = 6 ERRinvdevice = 7 ERRqfull = 49 ERRqtoobig = 50 ERRinvpfid = 52 ERRsmbcmd = 64 ERRsrverror = 65 ERRfilespecs = 67 ERRbadlink = 68 ERRbadpermits = 69 ERRbadpid = 70 ERRsetattrmode = 71 ERRpaused = 81 ERRmsgoff = 82 ERRnoroom = 83 ERRrmuns = 87 ERRtimeout = 88 ERRnoresource = 89 ERRtoomanyuids = 90 ERRbaduid = 91 ERRuseMPX = 250 ERRuseSTD = 251 ERRcontMPX = 252 ERRbadPW = None ERRnosupport = 0 ERRunknownsmb = 22 ERRnowrite = 19 ERRbadunit = 20 ERRnotready = 21 ERRbadcmd = 22 ERRdata = 23 ERRbadreq = 24 ERRseek = 25 ERRbadmedia = 26 ERRbadsector = 27 ERRnopaper = 28 ERRwrite = 29 ERRread = 30 ERRgeneral = 31 ERRwrongdisk = 34 ERRFCBunavail = 35 ERRsharebufexc = 36 ERRdiskfull = 39 hard_msgs = { 19: ('ERRnowrite', 'Attempt to write on write-protected diskette.'), 20: ('ERRbadunit', 'Unknown unit.'), 21: ('ERRnotready', 'Drive not ready.'), 22: ('ERRbadcmd', 'Unknown command.'), 23: ('ERRdata', 'Data error (CRC).'), 24: ('ERRbadreq', 'Bad request structure length.'), 25: ('ERRseek', 'Seek error.'), 26: ('ERRbadmedia', 'Unknown media type.'), 27: ('ERRbadsector', 'Sector not found.'), 28: ('ERRnopaper', 'Printer out of paper.'), 29: ('ERRwrite', 'Write fault.'), 30: ('ERRread', 'Read fault.'), 31: ('ERRgeneral', 'General failure.'), 32: ('ERRbadshare', 'An open conflicts with an existing open.'), 33: ('ERRlock', 'A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process.'), 34: ('ERRwrongdisk', 'The wrong disk was found in a drive.'), 35: ('ERRFCBUnavail', 'No FCBs are available to process request.'), 36: ('ERRsharebufexc', 'A sharing buffer has been exceeded.') } dos_msgs = { ERRbadfunc: ('ERRbadfunc', 'Invalid function.'), ERRbadfile: ('ERRbadfile', 'File not found.'), ERRbadpath: ('ERRbadpath', 'Directory invalid.'), ERRnofids: ('ERRnofids', 'No file descriptors available'), ERRnoaccess: ('ERRnoaccess', 'Access denied.'), ERRbadfid: ('ERRbadfid', 'Invalid file handle.'), ERRbadmcb: ('ERRbadmcb', 'Memory control blocks destroyed.'), ERRnomem: ('ERRnomem', 'Insufficient server memory to perform the requested function.'), ERRbadmem: ('ERRbadmem', 'Invalid memory block address.'), ERRbadenv: ('ERRbadenv', 'Invalid environment.'), 11: ('ERRbadformat', 'Invalid format.'), ERRbadaccess: ('ERRbadaccess', 'Invalid open mode.'), ERRbaddata: ('ERRbaddata', 'Invalid data.'), ERRres: ('ERRres', 'reserved.'), ERRbaddrive: ('ERRbaddrive', 'Invalid drive specified.'), ERRremcd: ('ERRremcd', "A Delete Directory request attempted to remove the server's current directory."), ERRdiffdevice: ('ERRdiffdevice', 'Not same device.'), ERRnofiles: ('ERRnofiles', 'A File Search command can find no more files matching the specified criteria.'), ERRbadshare: ('ERRbadshare', 'The sharing mode specified for an Open conflicts with existing FIDs on the file.'), ERRlock: ('ERRlock', 'A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process.'), ERRunsup: ('ERRunsup', 'The operation is unsupported'), ERRnosuchshare: ('ERRnosuchshare', 'You specified an invalid share name'), ERRfilexists: ('ERRfilexists', 'The file named in a Create Directory, Make New File or Link request already exists.'), ERRinvalidname: ('ERRinvalidname', 'Invalid name'), ERRbadpipe: ('ERRbadpipe', 'Pipe invalid.'), ERRpipebusy: ('ERRpipebusy', 'All instances of the requested pipe are busy.'), ERRpipeclosing: ('ERRpipeclosing', 'Pipe close in progress.'), ERRnotconnected: ('ERRnotconnected', 'No process on other end of pipe.'), ERRmoredata: ('ERRmoredata', 'There is more data to be returned.'), ERRinvgroup: ('ERRinvgroup', 'Invalid workgroup (try the -W option)'), ERRlogonfailure: ('ERRlogonfailure', 'Logon failure'), ERRdiskfull: ('ERRdiskfull', 'Disk full'), ERRgeneral: ('ERRgeneral', 'General failure'), ERRunknownlevel: ('ERRunknownlevel', 'Unknown info level') } server_msgs = { 1: ('ERRerror', 'Non-specific error code.'), 2: ('ERRbadpw', 'Bad password - name/password pair in a Tree Connect or Session Setup are invalid.'), 3: ('ERRbadtype', 'reserved.'), 4: ('ERRaccess', 'The requester does not have the necessary access rights within the specified context for the requested function. The context is defined by the TID or the UID.'), 5: ('ERRinvnid', 'The tree ID (TID) specified in a command was invalid.'), 6: ('ERRinvnetname', 'Invalid network name in tree connect.'), 7: ('ERRinvdevice', 'Invalid device - printer request made to non-printer connection or non-printer request made to printer connection.'), 49: ('ERRqfull', 'Print queue full (files) -- returned by open print file.'), 50: ('ERRqtoobig', 'Print queue full -- no space.'), 51: ('ERRqeof', 'EOF on print queue dump.'), 52: ('ERRinvpfid', 'Invalid print file FID.'), 64: ('ERRsmbcmd', 'The server did not recognize the command received.'), 65: ('ERRsrverror', 'The server encountered an internal error, e.g., system file unavailable.'), 67: ('ERRfilespecs', 'The file handle (FID) and pathname parameters contained an invalid combination of values.'), 68: ('ERRreserved', 'reserved.'), 69: ('ERRbadpermits', 'The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute.'), 70: ('ERRreserved', 'reserved.'), 71: ('ERRsetattrmode', 'The attribute mode in the Set File Attribute request is invalid.'), 81: ('ERRpaused', 'Server is paused.'), 82: ('ERRmsgoff', 'Not receiving messages.'), 83: ('ERRnoroom', 'No room to buffer message.'), 87: ('ERRrmuns', 'Too many remote user names.'), 88: ('ERRtimeout', 'Operation timed out.'), 89: ('ERRnoresource', 'No resources currently available for request.'), 90: ('ERRtoomanyuids', 'Too many UIDs active on this session.'), 91: ('ERRbaduid', 'The UID is not known as a valid ID on this session.'), 250: ('ERRusempx', 'Temp unable to support Raw, use MPX mode.'), 251: ('ERRusestd', 'Temp unable to support Raw, use standard read/write.'), 252: ('ERRcontmpx', 'Continue in MPX mode.'), 253: ('ERRreserved', 'reserved.'), 254: ('ERRreserved', 'reserved.'), 65535: ('ERRnosupport', 'Function not supported.') } ERRDOS = 1 error_classes = { 0: ('SUCCESS', { }), ERRDOS: ('ERRDOS', dos_msgs), 2: ('ERRSRV', server_msgs), 3: ('ERRHRD', hard_msgs), 4: ('ERRXOS', { }), 225: ('ERRRMX1', { }), 226: ('ERRRMX2', { }), 227: ('ERRRMX3', { }), 255: ('ERRCMD', { }) } def __init__(self, str, error_class, error_code): self.args = str self.error_class = error_class self.error_code = error_code def get_error_class(self): return self.error_class def get_error_code(self): return self.error_code def __str__(self): error_class = SessionError.error_classes.get(self.error_class, None) if not error_class: error_code_str = self.error_code error_class_str = self.error_class else: error_class_str = error_class[0] error_code = error_class[1].get(self.error_code, None) if not error_code: error_code_str = self.error_code else: error_code_str = '%s(%s)' % error_code return 'SessionError: %s, class: %s, code: %s' % (self.args, error_class_str, error_code_str) class UnsupportedFeature(Exception): pass class SharedDevice: def __init__(self, name, type, comment): self._SharedDevice__name = name self._SharedDevice__type = type self._SharedDevice__comment = comment def get_name(self): return self._SharedDevice__name def get_type(self): return self._SharedDevice__type def get_comment(self): return self._SharedDevice__comment def __repr__(self): return '<SharedDevice instance: name=' + self._SharedDevice__name + ', type=' + str(self._SharedDevice__type) + ', comment="' + self._SharedDevice__comment + '">' class SharedFile: def __init__(self, ctime, atime, mtime, filesize, allocsize, attribs, shortname, longname): self._SharedFile__ctime = ctime self._SharedFile__atime = atime self._SharedFile__mtime = mtime self._SharedFile__filesize = filesize self._SharedFile__allocsize = allocsize self._SharedFile__attribs = attribs try: self._SharedFile__shortname = shortname[:string.index(shortname, '\x00')] except ValueError: self._SharedFile__shortname = shortname try: self._SharedFile__longname = longname[:string.index(longname, '\x00')] except ValueError: self._SharedFile__longname = longname def get_ctime(self): return self._SharedFile__ctime def get_ctime_epoch(self): return self._SharedFile__convert_smbtime(self._SharedFile__ctime) def get_mtime(self): return self._SharedFile__mtime def get_mtime_epoch(self): return self._SharedFile__convert_smbtime(self._SharedFile__mtime) def get_atime(self): return self._SharedFile__atime def get_atime_epoch(self): return self._SharedFile__convert_smbtime(self._SharedFile__atime) def get_filesize(self): return self._SharedFile__filesize def get_allocsize(self): return self._SharedFile__allocsize def get_attributes(self): return self._SharedFile__attribs def is_archive(self): return self._SharedFile__attribs & ATTR_ARCHIVE def is_compressed(self): return self._SharedFile__attribs & ATTR_COMPRESSED def is_normal(self): return self._SharedFile__attribs & ATTR_NORMAL def is_hidden(self): return self._SharedFile__attribs & ATTR_HIDDEN def is_readonly(self): return self._SharedFile__attribs & ATTR_READONLY def is_temporary(self): return self._SharedFile__attribs & ATTR_TEMPORARY def is_directory(self): return self._SharedFile__attribs & ATTR_DIRECTORY def is_system(self): return self._SharedFile__attribs & ATTR_SYSTEM def get_shortname(self): return self._SharedFile__shortname def get_longname(self): return self._SharedFile__longname def __repr__(self): return '<SharedFile instance: shortname="' + self._SharedFile__shortname + '", longname="' + self._SharedFile__longname + '", filesize=' + str(self._SharedFile__filesize) + '>' def __convert_smbtime(self, t): x = t >> 32 y = t & 0xFFFFFFFFL geo_cal_offset = 11644473600.0 return (x * 4.0 * (1 << 30) + (y & 0xFFF00000L)) * 9.9999999999999995e-08 - geo_cal_offset class SMBMachine: def __init__(self, nbname, type, comment): self._SMBMachine__nbname = nbname self._SMBMachine__type = type self._SMBMachine__comment = comment def __repr__(self): return '<SMBMachine instance: nbname="' + self._SMBMachine__nbname + '", type=' + hex(self._SMBMachine__type) + ', comment="' + self._SMBMachine__comment + '">' class SMBDomain: def __init__(self, nbgroup, type, master_browser): self._SMBDomain__nbgroup = nbgroup self._SMBDomain__type = type self._SMBDomain__master_browser = master_browser def __repr__(self): return '<SMBDomain instance: nbgroup="' + self._SMBDomain__nbgroup + '", type=' + hex(self._SMBDomain__type) + ', master browser="' + self._SMBDomain__master_browser + '">' class NewSMBPacket(Structure): structure = (('Signature', '"\xffSMB'), ('Command', 'B=0'), ('ErrorClass', 'B=0'), ('_reserved', 'B=0'), ('ErrorCode', '<H=0'), ('Flags1', 'B=0'), ('Flags2', '<H=0'), ('Padding', '12s=""'), ('Tid', '<H=0xffff'), ('Pid', '<H=0'), ('Uid', '<H=0'), ('Mid', '<H=0'), ('Data', '*:')) def __init__(self, **kargs): Structure.__init__(self, **kargs) if not kargs.has_key('data'): self['Data'] = [] def addCommand(self, command): if len(self['Data']) == 0: self['Command'] = command.command else: self['Data'][-1]['Parameters']['AndXCommand'] = command.command self['Data'][-1]['Parameters']['AndXOffset'] = len(self) self['Data'].append(command) def isMoreData(self): if self['Command'] in [ SMB.SMB_COM_TRANSACTION, SMB.SMB_COM_READ_ANDX, SMB.SMB_COM_READ_RAW] and self['ErrorClass'] == 1: pass return self['ErrorCode'] == SessionError.ERRmoredata def isValidAnswer(self, cmd): if self['Command'] == cmd: if self['ErrorClass'] == 0 and self['ErrorCode'] == 0: return 1 elif self.isMoreData(): return 1 raise SessionError, ('SMB Library Error', self['ErrorClass'], self['ErrorCode']) else: raise UnsupportedFeature, 'Unexpected answer from server: Got %d, Expected %d' % (self['Command'], cmd) class SMBPacket: def __init__(self, data = ''): self._command = 0 self._error_class = 0 self._error_code = 0 self._flags = 0 self._flags2 = 0 self._pad = '\x00' * 12 self._tid = 0 self._pid = 0 self._uid = 0 self._mid = 0 self._wordcount = 0 self._parameter_words = '' self._bytecount = 0 self._buffer = '' if data != '': self._command = ord(data[4]) self._error_class = ord(data[5]) self._error_code = unpack('<H', data[7:9])[0] self._flags = ord(data[9]) self._flags2 = unpack('<H', data[10:12])[0] self._tid = unpack('<H', data[24:26])[0] self._pid = unpack('<H', data[26:28])[0] self._uid = unpack('<H', data[28:30])[0] self._mid = unpack('<H', data[30:32])[0] self._wordcount = ord(data[32]) self._parameter_words = data[33:33 + self._wordcount * 2] self._bytecount = ord(data[33 + self._wordcount * 2]) self._buffer = data[35 + self._wordcount * 2:] def set_command(self, command): self._command = command def set_error_class(self, error_class): self._error_class = error_class def set_error_code(self, error_code): self._error_code = error_code def set_flags(self, flags): self._flags = flags def set_flags2(self, flags2): self._flags2 = flags2 def set_pad(self, pad): self._pad = pad def set_tid(self, tid): self._tid = tid def set_pid(self, pid): self._pid = pid def set_uid(self, uid): self._uid = uid def set_mid(self, mid): self._mid = mid def set_parameter_words(self, param): self._parameter_words = param self._wordcount = len(param) / 2 def set_buffer(self, buffer): if type(buffer) is types.UnicodeType: raise Exception('SMBPacket: Invalid buffer. Received unicode') self._buffer = buffer self._bytecount = len(buffer) def get_command(self): return self._command def get_error_class(self): return self._error_class def get_error_code(self): return self._error_code def get_flags(self): return self._flags def get_flags2(self): return self._flags2 def get_pad(self): return self._pad def get_tid(self): return self._tid def get_pid(self): return self._pid def get_uid(self): return self._uid def get_mid(self): return self._mid def get_parameter_words(self): return self._parameter_words def get_wordcount(self): return self._wordcount def get_bytecount(self): return self._bytecount def get_buffer(self): return self._buffer def rawData(self): data = pack('<4sBBBHBH12sHHHHB', '\xffSMB', self._command, self._error_class, 0, self._error_code, self._flags, self._flags2, self._pad, self._tid, self._pid, self._uid, self._mid, self._wordcount) + self._parameter_words + pack('<H', self._bytecount) + self._buffer return data class TRANSHeader: def __init__(self, params = '', data = ''): self._total_param_count = 0 self._total_data_count = 0 self._max_param_count = 0 self._max_data_count = 0 self._max_setup_count = 0 self._flags = 0 self._timeout = 0 self._param_count = 0 self._param_offset = 0 self._data_count = 0 self._data_offset = 0 self._setup_count = 0 self._setup = 0 self._name = '' self._pad = '' self._parameters = 0 self._data = 0 if data != '' and params != '': (self._total_param_count, self._total_data_count, _, self._param_count, self._param_offset, self._param_displacement, self._data_count, self._data_offset, self._data_displacement, self._setup_count, _) = unpack('<HHHHHHHHHBB', params) self._data = data[-(self._data_count):] def set_flags(self, flags): self._flags = flags def set_name(self, name): self._name = name def set_setup(self, setup): self._setup = setup def set_parameters(self, parameters): self._parameters = parameters self._total_param_count = len(parameters) def set_data(self, data): self._data = data self._total_data_count = len(data) def set_max_data_count(self, max): self._max_data_count = max def set_max_param_count(self, max): self._max_param_count = max def get_rawParameters(self): self._param_offset = 32 + 3 + 28 + len(self._setup) + len(self._name) self._data_offset = self._param_offset + len(self._parameters) return pack('<HHHHBBHLHHHHHBB', self._total_param_count, self._total_data_count, self._max_param_count, self._max_data_count, self._max_setup_count, 0, self._flags, self._timeout, 0, self._total_param_count, self._param_offset, self._total_data_count, self._data_offset, len(self._setup) / 2, 0) + self._setup def get_data(self): return self._data def rawData(self): return self._name + self._parameters + self._data class SMBCommand(Structure): structure = (('WordCount', 'B=len(Parameters)/2'), ('_ParametersLength', '_-Parameters', 'WordCount*2'), ('Parameters', ':'), ('ByteCount', '<H-Data'), ('Data', ':')) def __init__(self, commandOrData = None, data = None, **kargs): if type(commandOrData) == type(0): self.command = commandOrData elif not data: pass data = commandOrData Structure.__init__(self, data = data, **kargs) if data is None: self['Parameters'] = '' self['Data'] = '' class AsciiOrUnicodeStructure(Structure): def __init__(self, flags = 0, **kargs): if flags & SMB.FLAGS2_UNICODE: self.structure = self.UnicodeStructure else: self.structure = self.AsciiStructure return Structure.__init__(self, **kargs) class SMBCommand_Parameters(Structure): pass class SMBAndXCommand_Parameters(Structure): commonHdr = (('AndXCommand', 'B=0xff'), ('_reserved', 'B=0'), ('AndXOffset', '<H=0')) structure = (('Data', ':=""'),) class SMBSessionSetupAndX_Parameters(SMBAndXCommand_Parameters): structure = (('MaxBuffer', '<H'), ('MaxMpxCount', '<H'), ('VCNumber', '<H'), ('SessionKey', '<L'), ('AnsiPwdLength', '<H'), ('UnicodePwdLength', '<H'), ('_reserved', '<L=0'), ('Capabilities', '<L')) class SMBSessionSetupAndX_Data(AsciiOrUnicodeStructure): AsciiStructure = (('AnsiPwdLength', '_-AnsiPwd'), ('UnicodePwdLength', '_-UnicodePwd'), ('AnsiPwd', ':=""'), ('UnicodePwd', ':=""'), ('Account', 'z=""'), ('PrimaryDomain', 'z=""'), ('NativeOS', 'z=""'), ('NativeLanMan', 'z=""')) UnicodeStructure = (('AnsiPwdLength', '_-AnsiPwd'), ('UnicodePwdLength', '_-UnicodePwd'), ('AnsiPwd', ':=""'), ('UnicodePwd', ':=""'), ('Account', 'w=""'), ('PrimaryDomain', 'w=""'), ('NativeOS', 'w=""'), ('NativeLanMan', 'w=""')) class SMBSessionSetupAndXResponse_Parameters(SMBAndXCommand_Parameters): structure = (('Action', '<H'),) class SMBSessionSetupAndXResponse_Data(AsciiOrUnicodeStructure): AsciiStructure = (('NativeOS', 'z=""'), ('NativeLanMan', 'z=""'), ('PrimaryDomain', 'z=""')) UnicodeStructure = (('NativeOS', 'w=""'), ('NativeLanMan', 'w=""'), ('PrimaryDomain', 'w=""')) class SMBTreeConnect_Parameters(SMBCommand_Parameters): structure = () class SMBTreeConnect_Data(SMBCommand_Parameters): structure = (('PathFormat', '"\x04'), ('Path', 'z'), ('PasswordFormat', '"\x04'), ('Password', 'z'), ('ServiceFormat', '"\x04'), ('Service', 'z')) class SMBTreeConnectAndX_Parameters(SMBAndXCommand_Parameters): structure = (('Flags', '<H=0'), ('PasswordLength', '<H')) class SMBTreeConnectAndX_Data(SMBCommand_Parameters): structure = (('_PasswordLength', '_-Password'), ('Password', ':'), ('Path', 'z'), ('Service', 'z')) class SMBNtCreateAndX_Parameters(SMBAndXCommand_Parameters): structure = (('_reserved', 'B=0'), ('FileNameLength', '<H'), ('CreateFlags', '<L'), ('RootFid', '<L=0'), ('AccessMask', '<L'), ('AllocationSizeLo', '<L=0'), ('AllocationSizeHi', '<L=0'), ('FileAttributes', '<L=0'), ('ShareAccess', '<L=3'), ('Disposition', '<L=1'), ('CreateOptions', '<L'), ('Impersonation', '<L=2'), ('SecurityFlags', 'B=3')) class SMBNtCreateAndXResponse_Parameters(SMBAndXCommand_Parameters): structure = (('OplockLevel', 'B=0'), ('Fid', '<H'), ('CreateAction', '<L'), ('CraetionTimeLo', '<L=0'), ('CraetionTimeHi', '<L=0'), ('AccessTimeLo', '<L=0'), ('AccessTimeHi', '<L=0'), ('LastWriteTimeLo', '<L=0'), ('LastWriteTimeHi', '<L=0'), ('ChangeTimeLo', '<L=0'), ('ChangeTimeHi', '<L=0'), ('FileAttributes', '<L=0x80'), ('AllocationSizeLo', '<L=0'), ('AllocationSizeHi', '<L=0'), ('EndOfFileLo', '<L=0'), ('EndOfFileHi', '<L=0'), ('FileType', '<H=0'), ('IPCState', '<H=0'), ('IsDirectory', 'B')) class SMBNtCreateAndX_Data(Structure): structure = (('FileName', 'z'),) class SMBOpenAndX_Parameters(SMBAndXCommand_Parameters): structure = (('Flags', '<H=0'), ('DesiredAccess', '<H=0'), ('SearchAttributes', '<H=0'), ('FileAttributes', '<H=0'), ('CreationTime', '<L=0'), ('OpenMode', '<H=1'), ('AllocationSize', '<L=0'), ('Reserved', '8s=""')) class SMBOpenAndX_Data(SMBNtCreateAndX_Data): pass class SMBOpenAndXResponse_Parameters(SMBAndXCommand_Parameters): structure = (('Fid', '<H=0'), ('FileAttributes', '<H=0'), ('LastWriten', '<L=0'), ('FileSize', '<L=0'), ('GrantedAccess', '<H=0'), ('FileType', '<H=0'), ('IPCState', '<H=0'), ('Action', '<H=0'), ('ServerFid', '<L=0'), ('_reserved', '<H=0')) class SMBWrite_Parameters(SMBCommand_Parameters): structure = (('Fid', '<H'), ('Count', '<H'), ('Offset', '<L'), ('Remaining', '<H')) class SMBWrite_Data(Structure): structure = (('BufferFormat', '<B=1'), ('DataLength', '<H-Data'), ('Data', ':')) class SMBWriteAndX_Parameters(SMBAndXCommand_Parameters): structure = (('Fid', '<H'), ('Offset', '<L'), ('_reserved', '<L=0xff'), ('WriteMode', '<H=8'), ('Remaining', '<H'), ('DataLength_Hi', '<H=0'), ('DataLength', '<H'), ('DataOffset', '<H=0'), ('HighOffset', '<L=0')) class SMBWriteRaw_Parameters(SMBCommand_Parameters): structure = (('Fid', '<H'), ('Count', '<H'), ('_reserved', '<H=0'), ('Offset', '<L'), ('Timeout', '<L=0'), ('WriteMode', '<H=0'), ('_reserved2', '<L=0'), ('DataLength', '<H'), ('DataOffset', '<H=0')) class SMBRead_Parameters(SMBCommand_Parameters): structure = (('Fid', '<H'), ('Count', '<H'), ('Offset', '<L'), ('Remaining', '<H=Count')) class SMBReadResponse_Parameters(Structure): structure = (('Count', '<H=0'), ('_reserved', '"\x00\x00\x00\x00\x00\x00\x00\x00')) class SMBReadResponse_Data(Structure): structure = (('BufferFormat', '<B'), ('DataLength', '<H-Data'), ('Data', ':')) class SMBReadRaw_Parameters(SMBCommand_Parameters): structure = (('Fid', '<H'), ('Offset', '<L'), ('MaxCount', '<H'), ('MinCount', '<H=MaxCount'), ('Timeout', '<L=0'), ('_reserved', '<H=0')) class SMBReadAndX_Parameters(SMBAndXCommand_Parameters): structure = (('Fid', '<H'), ('Offset', '<L'), ('MaxCount', '<H'), ('MinCount', '<H=MaxCount'), ('_reserved', '<L=0xffffffff'), ('Remaining', '<H=MaxCount'), ('HighOffset', '<L=0')) class SMBReadAndXResponse_Parameters(SMBAndXCommand_Parameters): structure = (('Remaining', '<H=0'), ('DataMode', '<H=0'), ('_reserved', '<H=0'), ('DataCount', '<H'), ('DataOffset', '<H'), ('DataCount_Hi', '<L'), ('_reserved2', '"\x00\x00\x00\x00\x00\x00')) class SMBOpen_Parameters(SMBCommand_Parameters): structure = (('DesiredAccess', '<H=0'), ('SearchAttributes', '<H=0')) class SMBOpen_Data(Structure): structure = (('FileNameFormat', '"\x04'), ('FileName', 'z')) class SMBOpenResponse_Parameters(SMBCommand_Parameters): structure = (('Fid', '<H=0'), ('FileAttributes', '<H=0'), ('LastWriten', '<L=0'), ('FileSize', '<L=0'), ('GrantedAccess', '<H=0')) class NTLMDialect(SMBPacket): def __init__(self, data = ''): SMBPacket.__init__(self, data) self._selected_dialect = 0 self._security_mode = 0 self._max_mpx = 0 self._max_vc = 0 self._max_buffer = 0 self._max_raw = 0 self._session_key = 0 self._lsw_capabilities = 0 self._msw_capabilities = 0 self._utc_high = 0 self._utc_low = 0 self._minutes_utc = 0 self._encryption_key_len = 0 self._encryption_key = '' self._server_domain = '' self._server_name = '' if data: (self._selected_dialect, self._security_mode, self._max_mpx, self._max_vc) = unpack('<HBHH', self.get_parameter_words()[:7]) (self._max_buffer, self._max_raw, self._session_key, self._lsw_capabilities, self._msw_capabilities) = unpack('<lllHH', self.get_parameter_words()[7:16 + 7]) (self._utc_low, self._utc_high, self._minutes_utc, self._encryption_key_len) = unpack('<LLhB', self.get_parameter_words()[23:34]) if self._encryption_key_len > 0 and len(self.get_buffer()) >= self._encryption_key_len: self._encryption_key = self.get_buffer()[:self._encryption_key_len] buf = self.get_buffer() self._server_name = '<Unknown>' self._server_domain = '<Unknown>' try: if self._lsw_capabilities & 3: offset = self._encryption_key_len if offset & 1: offset += 1 end = offset while ord(buf[end]) or ord(buf[end + 1]): end += 2 self._server_domain = unicode(buf[offset:end], 'utf_16_le') end += 2 offset = end while ord(buf[end]) or ord(buf[end + 1]): end += 2 self._server_name = unicode(buf[offset:end], 'utf_16_le') else: offset = self._encryption_key_len idx1 = string.find(buf, '\x00', offset) if idx1 != -1: self._server_domain = buf[offset:idx1] idx2 = string.find(buf, '\x00', idx1 + 1) if idx2 != -1: self._server_name = buf[idx1 + 1:idx2] else: self._encryption_key = '' def get_selected_dialect(self): return self._selected_dialect def get_security_mode(self): return self._security_mode def get_max_mpx(self): return self._max_mpx def get_max_vc(self): return self._max_vc def get_max_buffer(self): return self._max_buffer def get_max_raw(self): return self._max_raw def get_session_key(self): return self._session_key def get_lsw_capabilities(self): return self._lsw_capabilities def get_msw_capabilities(self): return self._msw_capabilities def get_utc(self): return (self._utc_high, self._utc_low) def get_minutes_utc(self): return self._minutes_utc def get_encryption_key_len(self): return self._encryption_key_len def get_encryption_key(self): return self._encryption_key def get_server_domain(self): return self._server_domain def get_server_name(self): return self._server_name def is_auth_mode(self): return self._security_mode & SMB.SECURITY_AUTH_MASK def is_share_mode(self): return self._security_mode & SMB.SECURITY_SHARE_MASK def is_rawmode(self): return self._lsw_capabilities & SMB.CAP_RAW_MODE class SMB: SMB_COM_CREATE_DIRECTORY = 0 SMB_COM_DELETE_DIRECTORY = 1 SMB_COM_OPEN = 2 SMB_COM_CREATE = 3 SMB_COM_CLOSE = 4 SMB_COM_FLUSH = 5 SMB_COM_DELETE = 6 SMB_COM_RENAME = 7 SMB_COM_QUERY_INFORMATION = 8 SMB_COM_SET_INFORMATION = 9 SMB_COM_READ = 10 SMB_COM_WRITE = 11 SMB_COM_LOCK_BYTE_RANGE = 12 SMB_COM_UNLOCK_BYTE_RANGE = 13 SMB_COM_CREATE_TEMPORARY = 14 SMB_COM_CREATE_NEW = 15 SMB_COM_CHECK_DIRECTORY = 16 SMB_COM_PROCESS_EXIT = 17 SMB_COM_SEEK = 18 SMB_COM_LOCK_AND_READ = 19 SMB_COM_WRITE_AND_UNLOCK = 20 SMB_COM_READ_RAW = 26 SMB_COM_READ_MPX = 27 SMB_COM_READ_MPX_SECONDARY = 28 SMB_COM_WRITE_RAW = 29 SMB_COM_WRITE_MPX = 30 SMB_COM_WRITE_MPX_SECONDARY = 31 SMB_COM_WRITE_COMPLETE = 32 SMB_COM_QUERY_SERVER = 33 SMB_COM_SET_INFORMATION2 = 34 SMB_COM_QUERY_INFORMATION2 = 35 SMB_COM_LOCKING_ANDX = 36 SMB_COM_TRANSACTION = 37 SMB_COM_TRANSACTION_SECONDARY = 38 SMB_COM_IOCTL = 39 SMB_COM_IOCTL_SECONDARY = 40 SMB_COM_COPY = 41 SMB_COM_MOVE = 42 SMB_COM_ECHO = 43 SMB_COM_WRITE_AND_CLOSE = 44 SMB_COM_OPEN_ANDX = 45 SMB_COM_READ_ANDX = 46 SMB_COM_WRITE_ANDX = 47 SMB_COM_NEW_FILE_SIZE = 48 SMB_COM_CLOSE_AND_TREE_DISC = 49 SMB_COM_TRANSACTION2 = 50 SMB_COM_TRANSACTION2_SECONDARY = 51 SMB_COM_FIND_CLOSE2 = 52 SMB_COM_FIND_NOTIFY_CLOSE = 53 SMB_COM_TREE_CONNECT = 112 SMB_COM_TREE_DISCONNECT = 113 SMB_COM_NEGOTIATE = 114 SMB_COM_SESSION_SETUP_ANDX = 115 SMB_COM_LOGOFF_ANDX = 116 SMB_COM_TREE_CONNECT_ANDX = 117 SMB_COM_QUERY_INFORMATION_DISK = 128 SMB_COM_SEARCH = 129 SMB_COM_FIND = 130 SMB_COM_FIND_UNIQUE = 131 SMB_COM_FIND_CLOSE = 132 SMB_COM_NT_TRANSACT = 160 SMB_COM_NT_TRANSACT_SECONDARY = 161 SMB_COM_NT_CREATE_ANDX = 162 SMB_COM_NT_CANCEL = 164 SMB_COM_NT_RENAME = 165 SMB_COM_OPEN_PRINT_FILE = 192 SMB_COM_WRITE_PRINT_FILE = 193 SMB_COM_CLOSE_PRINT_FILE = 194 SMB_COM_GET_PRINT_QUEUE = 195 SMB_COM_READ_BULK = 216 SMB_COM_WRITE_BULK = 217 SMB_COM_WRITE_BULK_DATA = 218 SECURITY_SHARE_MASK = 1 SECURITY_SHARE_SHARE = 0 SECURITY_SHARE_USER = 1 SECURITY_AUTH_MASK = 2 SECURITY_AUTH_ENCRYPTED = 2 SECURITY_AUTH_PLAINTEXT = 0 RAW_READ_MASK = 1 RAW_WRITE_MASK = 2 CAP_RAW_MODE = 1 CAP_MPX_MODE = 2 CAP_UNICODE = 4 CAP_LARGE_FILES = 8 CAP_EXTENDED_SECURITY = 0x80000000L FLAGS1_PATHCASELESS = 8 FLAGS2_LONG_FILENAME = 1 FLAGS2_USE_NT_ERRORS = 16384 FLAGS2_UNICODE = 32768 def __init__(self, remote_name, remote_host, my_name = None, host_type = nmb.TYPE_SERVER, sess_port = nmb.NETBIOS_SESSION_PORT, timeout = None): self._SMB__uid = 0 self._SMB__server_os = '' self._SMB__server_lanman = '' self._SMB__server_domain = '' self._SMB__remote_name = string.upper(remote_name) self._SMB__is_pathcaseless = 0 self._SMB__ntlm_dialect = 0 self._SMB__sess = None if timeout == None: self._SMB__timeout = 30 else: self._SMB__timeout = timeout if not my_name: my_name = socket.gethostname() i = string.find(my_name, '.') if i > -1: my_name = my_name[:i] try: self._SMB__sess = nmb.NetBIOSSession(my_name, remote_name, remote_host, host_type, sess_port, timeout) except socket.error: ex = None raise ex self._SMB__neg_session() if not self._SMB__ntlm_dialect.is_auth_mode() == SMB.SECURITY_AUTH_PLAINTEXT: if not self._SMB__ntlm_dialect.is_auth_mode() == SMB.SECURITY_AUTH_ENCRYPTED and self._SMB__ntlm_dialect.get_encryption_key() or self._SMB__ntlm_dialect.get_encryption_key_len() >= 8: raise AssertionError if self._SMB__ntlm_dialect.is_share_mode() == SMB.SECURITY_SHARE_SHARE: self.login('', '') def set_timeout(self, timeout): self._SMB__timeout = timeout def __del__(self): if self._SMB__sess: self._SMB__sess.close() def __decode_smb(self, data): (_, cmd, err_class, _, err_code, flags1, flags2, _, tid, pid, uid, mid, wcount) = unpack('<4sBBBHBH12sHHHHB', data[:33]) param_end = 33 + wcount * 2 return (cmd, err_class, err_code, flags1, flags2, tid, uid, mid, data[33:param_end], data[param_end + 2:]) def recvSMB(self): r = self._SMB__sess.recv_packet(self._SMB__timeout) return NewSMBPacket(data = r.get_trailer()) def recv_packet(self): r = self._SMB__sess.recv_packet(self._SMB__timeout) return SMBPacket(r.get_trailer()) def __decode_trans(self, params, data): (totparamcnt, totdatacnt, _, paramcnt, paramoffset, paramds, datacnt, dataoffset, datads, setupcnt) = unpack('<HHHHHHHHHB', params[:19]) if paramcnt + paramds < totparamcnt or datacnt + datads < totdatacnt: has_more = 1 else: has_more = 0 paramoffset = paramoffset - 55 - setupcnt * 2 dataoffset = dataoffset - 55 - setupcnt * 2 return (has_more, params[20:20 + setupcnt * 2], data[paramoffset:paramoffset + paramcnt], data[dataoffset:dataoffset + datacnt]) def sendSMB(self, smb): smb['Uid'] = self._SMB__uid smb['Pid'] = os.getpid() self._SMB__sess.send_packet(str(smb)) def send_smb(self, s): s.set_uid(self._SMB__uid) s.set_pid(os.getpid()) self._SMB__sess.send_packet(s.rawData()) def __send_smb_packet(self, cmd, flags, flags2, tid, mid, params = '', data = ''): smb = NewSMBPacket() smb['Flags'] = flags smb['Flags2'] = flags2 smb['Tid'] = tid smb['Mid'] = mid cmd = SMBCommand(cmd) smb.addCommand(cmd) cmd['Parameters'] = params cmd['Data'] = data self.sendSMB(smb) def isValidAnswer(self, s, cmd): while s.rawData(): if s.get_command() == cmd: if s.get_error_class() == 0 and s.get_error_code() == 0: return 1 else: raise SessionError, ('SMB Library Error', s.get_error_class(), s.get_error_code()) else: break s.get_command() == cmd return 0 def __neg_session(self): s = SMBPacket() s.set_command(SMB.SMB_COM_NEGOTIATE) s.set_buffer('\x02NT LM 0.12\x00') self.send_smb(s) while None: s = self.recv_packet() if self.isValidAnswer(s, SMB.SMB_COM_NEGOTIATE): self._SMB__ntlm_dialect = NTLMDialect(s.rawData()) if self._SMB__ntlm_dialect.get_selected_dialect() == 65535: raise UnsupportedFeature, 'Remote server does not know NT LM 0.12' if self._SMB__ntlm_dialect.get_lsw_capabilities() & SMB.CAP_EXTENDED_SECURITY: raise UnsupportedFeature, 'This version of pysmb does not support extended security validation. Please file a request for it.' self._SMB__is_pathcaseless = s.get_flags() & SMB.FLAGS1_PATHCASELESS return 1 continue return 0 def tree_connect(self, path, password = '', service = SERVICE_ANY): if password: if self._SMB__ntlm_dialect.get_encryption_key(): password = self.get_ntlmv1_response(ntlm.compute_lmhash(password)) if not unicode_support: if unicode_convert: path = str(path) else: raise Except('SMB: Can\t conver path from unicode!') smb = NewSMBPacket() smb['Flags1'] = 8 treeConnect = SMBCommand(SMB.SMB_COM_TREE_CONNECT) treeConnect['Parameters'] = SMBTreeConnect_Parameters() treeConnect['Data'] = SMBTreeConnect_Data() treeConnect['Data']['Path'] = path.upper() treeConnect['Data']['Password'] = password treeConnect['Data']['Service'] = service smb.addCommand(treeConnect) self.sendSMB(smb) while None: smb = self.recvSMB() if smb.isValidAnswer(SMB.SMB_COM_TREE_CONNECT): return smb['Tid'] return smb['Tid'] def tree_connect_andx(self, path, password = None, service = SERVICE_ANY): if password: if self._SMB__ntlm_dialect.get_encryption_key(): password = self.get_ntlmv1_response(ntlm.compute_lmhash(password)) else: password = '\x00' if not unicode_support: if unicode_convert: path = str(path) else: raise Except('SMB: Can\t convert path from unicode!') smb = NewSMBPacket() smb['Flags1'] = 8 treeConnect = SMBCommand(SMB.SMB_COM_TREE_CONNECT_ANDX) treeConnect['Parameters'] = SMBTreeConnectAndX_Parameters() treeConnect['Data'] = SMBTreeConnectAndX_Data() treeConnect['Parameters']['PasswordLength'] = len(password) treeConnect['Data']['Password'] = password treeConnect['Data']['Path'] = path.upper() treeConnect['Data']['Service'] = service smb.addCommand(treeConnect) self.sendSMB(smb) while None: smb = self.recvSMB() if smb.isValidAnswer(SMB.SMB_COM_TREE_CONNECT_ANDX): return smb['Tid'] return smb['Tid'] connect_tree = tree_connect_andx def get_server_name(self): return self._SMB__ntlm_dialect.get_server_name() def get_session_key(self): return self._SMB__ntlm_dialect.get_session_key() def get_server_time(self): (high, low) = self._SMB__ntlm_dialect.get_utc() min = self._SMB__ntlm_dialect.get_minutes_utc() return samr.display_time(high, low, min) def disconnect_tree(self, tid): smb = NewSMBPacket() smb['Tid'] = tid smb.addCommand(SMBCommand(SMB.SMB_COM_TREE_DISCONNECT)) self.sendSMB(smb) smb = self.recvSMB() def open(self, tid, filename, open_mode, desired_access): smb = NewSMBPacket() smb['Flags'] = 8 smb['Flags2'] = SMB.FLAGS2_LONG_FILENAME smb['Tid'] = tid openFile = SMBCommand(SMB.SMB_COM_OPEN) openFile['Parameters'] = SMBOpen_Parameters() openFile['Parameters']['DesiredAccess'] = desired_access openFile['Parameters']['OpenMode'] = open_mode openFile['Parameters']['SearchAttributes'] = ATTR_READONLY | ATTR_HIDDEN | ATTR_ARCHIVE openFile['Data'] = SMBOpen_Data() openFile['Data']['FileName'] = filename smb.addCommand(openFile) self.sendSMB(smb) smb = self.recvSMB() if smb.isValidAnswer(SMB.SMB_COM_OPEN): openFileResponse = SMBCommand(smb['Data'][0]) openFileParameters = SMBOpenResponse_Parameters(openFileResponse['Parameters']) return (openFileParameters['Fid'], openFileParameters['FileAttributes'], openFileParameters['LastWriten'], openFileParameters['FileSize'], openFileParameters['GrantedAccess']) def open_andx(self, tid, filename, open_mode, desired_access): smb = NewSMBPacket() smb['Flags'] = 8 smb['Flags2'] = SMB.FLAGS2_LONG_FILENAME smb['Tid'] = tid openFile = SMBCommand(SMB.SMB_COM_OPEN_ANDX) openFile['Parameters'] = SMBOpenAndX_Parameters() openFile['Parameters']['DesiredAccess'] = desired_access openFile['Parameters']['OpenMode'] = open_mode openFile['Parameters']['SearchAttributes'] = ATTR_READONLY | ATTR_HIDDEN | ATTR_ARCHIVE openFile['Data'] = SMBOpenAndX_Data() openFile['Data']['FileName'] = filename smb.addCommand(openFile) self.sendSMB(smb) smb = self.recvSMB() if smb.isValidAnswer(SMB.SMB_COM_OPEN_ANDX): openFileResponse = SMBCommand(smb['Data'][0]) openFileParameters = SMBOpenAndXResponse_Parameters(openFileResponse['Parameters']) return (openFileParameters['Fid'], openFileParameters['FileAttributes'], openFileParameters['LastWriten'], openFileParameters['FileSize'], openFileParameters['GrantedAccess'], openFileParameters['FileType'], openFileParameters['IPCState'], openFileParameters['Action'], openFileParameters['ServerFid']) def close(self, tid, fid): s = SMBPacket() s.set_command(SMB.SMB_COM_CLOSE) s.set_tid(tid) s.set_parameter_words(pack('<HL', fid, 0)) self.send_smb(s) s = self.recv_packet() def send_trans(self, tid, setup, name, param, data, noAnswer = 0): t = TRANSHeader() s = SMBPacket() s.set_tid(tid) s.set_command(SMB.SMB_COM_TRANSACTION) s.set_flags(self._SMB__is_pathcaseless) s.set_flags2(SMB.FLAGS2_LONG_FILENAME) t.set_setup(setup) t.set_name(name) t.set_parameters(param) t.set_data(data) t.set_max_param_count(1024) t.set_max_data_count(65504) if noAnswer: t.set_flags(TRANS_NO_RESPONSE) s.set_parameter_words(t.get_rawParameters()) s.set_buffer(t.rawData()) self.send_smb(s) def __trans(self, tid, setup, name, param, data): data_len = len(data) name_len = len(name) param_len = len(param) setup_len = len(setup) if not setup_len & 1 == 0: raise AssertionError param_offset = name_len + setup_len + 63 data_offset = param_offset + param_len self._SMB__send_smb_packet(SMB.SMB_COM_TRANSACTION, self._SMB__is_pathcaseless, SMB.FLAGS2_LONG_FILENAME, tid, 0, pack('<HHHHBBHLHHHHHBB', param_len, data_len, 1024, 65504, 0, 0, 0, 0, 0, param_len, param_offset, data_len, data_offset, setup_len / 2, 0) + setup, name + param + data) def trans2(self, tid, setup, name, param, data): data_len = len(data) name_len = len(name) param_len = len(param) setup_len = len(setup) if not setup_len & 1 == 0: raise AssertionError param_offset = name_len + setup_len + 63 data_offset = param_offset + param_len self._SMB__send_smb_packet(SMB.SMB_COM_TRANSACTION2, self._SMB__is_pathcaseless, SMB.FLAGS2_LONG_FILENAME, tid, 0, pack('<HHHHBBHLHHHHHBB', param_len, data_len, 1024, self._SMB__ntlm_dialect.get_max_buffer(), 0, 0, 0, 0, 0, param_len, param_offset, data_len, data_offset, setup_len / 2, 0) + setup, name + param + data) def query_file_info(self, tid, fid): self.trans2(tid, '\x07\x00', '\x00', pack('<HH', fid, 263), '') while None: s = self.recv_packet() if self.isValidAnswer(s, SMB.SMB_COM_TRANSACTION2): (f1, f2) = unpack('<LL', s.get_buffer()[53:53 + 8]) return (f2 & 0xFFFFFFFFL) << 32 | f1 continue def __nonraw_retr_file(self, tid, fid, offset, datasize, callback): max_buf_size = self._SMB__ntlm_dialect.get_max_buffer() & -1024 read_offset = offset while read_offset < datasize: data = self.read_andx(tid, fid, read_offset, max_buf_size) callback(data) read_offset += len(data) def __raw_retr_file(self, tid, fid, offset, datasize, callback): max_buf_size = self._SMB__ntlm_dialect.get_max_buffer() & -1024 read_offset = offset while read_offset < datasize: data = self.read_raw(tid, fid, read_offset, 65535) if not data: data = self.read_andx(tid, fid, read_offset, max_buf_size) callback(data) read_offset += len(data) def __nonraw_stor_file(self, tid, fid, offset, datasize, callback): max_buf_size = self._SMB__ntlm_dialect.get_max_buffer() & -1024 write_offset = offset while None: data = callback(max_buf_size) if not data: break while None: s = self.recv_packet() if self.isValidAnswer(s, SMB.SMB_COM_WRITE_ANDX): offset = unpack('<H', s.get_parameter_words()[2:4])[0] write_offset = write_offset + unpack('<H', s.get_parameter_words()[4:6])[0] break continue def __raw_stor_file(self, tid, fid, offset, datasize, callback): write_offset = offset while None: read_data = callback(65535) if not read_data: break read_len = len(read_data) while None: s = self.recv_packet() if self.isValidAnswer(s, SMB.SMB_COM_WRITE_RAW): self._SMB__sess.send_packet(read_data) write_offset = write_offset + read_len break continue self._SMB__send_smb_packet(SMB.SMB_COM_CLOSE, 0, 0, tid, 0, pack('<HL', fid, 0), '') while None: s = self.recv_packet() if self.isValidAnswer(s, SMB.SMB_COM_CLOSE): if s.get_error_class() == 0 and s.get_error_code() == 0: return None def __browse_servers(self, server_flags, container_type, domain): tid = self.tree_connect_andx('\\\\' + self._SMB__remote_name + '\\IPC$') buf = StringIO() try: if server_flags & 0x80000000L: self._SMB__trans(tid, '', '\\PIPE\\LANMAN\x00', 'h\x00WrLehDz\x00' + 'B16BBDz\x00\x01\x00\xff\xff\x00\x00\x00\x80', '') else: self._SMB__trans(tid, '', '\\PIPE\\LANMAN\x00', 'h\x00WrLehDz\x00' + 'B16BBDz\x00\x01\x00\xff\xff' + pack('<l', server_flags) + domain + '\x00', '') servers = [] entry_count = 0 while None: s = self.recv_packet() if self.isValidAnswer(s, SMB.SMB_COM_TRANSACTION): (has_more, _, transparam, transdata) = self._SMB__decode_trans(s.get_parameter_words(), s.get_buffer()) if not entry_count: (status, convert, entry_count, avail_entry) = unpack('<HHHH', transparam[:8]) if status and status != 234: raise SessionError, ('Browse domains failed. (ErrClass: %d and ErrCode: %d)' % (128, status), 128, status) buf.write(transdata) if not has_more: server_data = buf.getvalue() for i in range(0, entry_count): (server, _, server_type, comment_offset) = unpack('<16s2sll', server_data[i * 26:i * 26 + 26]) idx = string.find(server, '\x00') idx2 = string.find(server_data, '\x00', comment_offset) if idx < 0: server = server[:idx] servers.append(container_type(server, server_type, server_data[comment_offset:idx2])) return servers finally: buf.close() self.disconnect_tree(tid) def get_server_domain(self): return self._SMB__server_domain def get_server_os(self): return self._SMB__server_os def get_server_lanman(self): return self._SMB__server_lanman def is_login_required(self): return self._SMB__ntlm_dialect.is_share_mode() == SMB.SECURITY_SHARE_USER def get_ntlmv1_response(self, key): challenge = self._SMB__ntlm_dialect.get_encryption_key() return ntlm.get_ntlmv1_response(key, challenge) def hmac_md5(self, key, data): import POW h = POW.Hmac(POW.MD5_DIGEST, key) h.update(data) result = h.mac() return result def get_ntlmv2_response(self, hash): ''' blob = RandomBytes( blobsize ); data = concat( ServerChallenge, 8, blob, blobsize ); hmac = hmac_md5( v2hash, 16, data, (8 + blobsize) ); v2resp = concat( hmac, 16, blob, blobsize ); ''' return '' def login(self, user, password, domain = '', lmhash = '', nthash = ''): if (password != '' or password == '') and lmhash == '' and nthash == '': self.login_plaintext_password(user, password) elif lmhash != '' or nthash != '': self.login_pass_the_hash(user, lmhash, nthash, domain) def _login(self, user, pwd_ansi, pwd_unicode, domain = ''): smb = NewSMBPacket() smb['Flags1'] = 8 sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX) sessionSetup['Parameters'] = SMBSessionSetupAndX_Parameters() sessionSetup['Data'] = SMBSessionSetupAndX_Data() sessionSetup['Parameters']['MaxBuffer'] = 65535 sessionSetup['Parameters']['MaxMpxCount'] = 2 sessionSetup['Parameters']['VCNumber'] = os.getpid() sessionSetup['Parameters']['SessionKey'] = self._SMB__ntlm_dialect.get_session_key() sessionSetup['Parameters']['AnsiPwdLength'] = len(pwd_ansi) sessionSetup['Parameters']['UnicodePwdLength'] = len(pwd_unicode) sessionSetup['Parameters']['Capabilities'] = SMB.CAP_RAW_MODE sessionSetup['Data']['AnsiPwd'] = pwd_ansi sessionSetup['Data']['UnicodePwd'] = pwd_unicode sessionSetup['Data']['Account'] = str(user) sessionSetup['Data']['PrimaryDomain'] = str(domain) sessionSetup['Data']['NativeOS'] = str(os.name) sessionSetup['Data']['NativeLanMan'] = 'pysmb' smb.addCommand(sessionSetup) self.sendSMB(smb) smb = self.recvSMB() if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX): self._SMB__uid = smb['Uid'] sessionResponse = SMBCommand(smb['Data'][0]) sessionParameters = SMBSessionSetupAndXResponse_Parameters(sessionResponse['Parameters']) sessionData = SMBSessionSetupAndXResponse_Data(flags = smb['Flags2'], data = sessionResponse['Data']) self._SMB__server_os = sessionData['NativeOS'] self._SMB__server_lanman = sessionData['NativeLanMan'] self._SMB__server_domain = sessionData['PrimaryDomain'] return 1 else: raise Exception('Error: Could not login successfully') def read(self, tid, fid, offset = 0, max_size = None, wait_answer = 1): if not max_size: max_size = self._SMB__ntlm_dialect.get_max_buffer() smb = NewSMBPacket() smb['Flags1'] = 24 smb['Flags2'] = 0 smb['Tid'] = tid read = SMBCommand(SMB.SMB_COM_READ) read['Parameters'] = SMBRead_Parameters() read['Parameters']['Fid'] = fid read['Parameters']['Offset'] = offset read['Parameters']['Count'] = max_size smb.addCommand(read) if wait_answer: answer = '' while None: ans = self.recvSMB() if ans.isValidAnswer(SMB.SMB_COM_READ): readResponse = SMBCommand(ans['Data'][0]) readParameters = SMBReadResponse_Parameters(readResponse['Parameters']) readData = SMBReadResponse_Data(readResponse['Data']) return readData['Data'] continue def read_andx(self, tid, fid, offset = 0, max_size = None, wait_answer = 1): if not max_size: max_size = self._SMB__ntlm_dialect.get_max_buffer() smb = NewSMBPacket() smb['Flags1'] = 24 smb['Flags2'] = 0 smb['Tid'] = tid readAndX = SMBCommand(SMB.SMB_COM_READ_ANDX) readAndX['Parameters'] = SMBReadAndX_Parameters() readAndX['Parameters']['Fid'] = fid readAndX['Parameters']['Offset'] = offset readAndX['Parameters']['MaxCount'] = max_size smb.addCommand(readAndX) if wait_answer: answer = '' while None: ans = self.recvSMB() if ans.isValidAnswer(SMB.SMB_COM_READ_ANDX): readAndXResponse = SMBCommand(ans['Data'][0]) readAndXParameters = SMBReadAndXResponse_Parameters(readAndXResponse['Parameters']) offset = readAndXParameters['DataOffset'] count = readAndXParameters['DataCount'] + 65536 * readAndXParameters['DataCount_Hi'] answer += str(ans)[offset:offset + count] if not ans.isMoreData(): return answer max_size = min(max_size, readAndXParameters['Remaining']) readAndX['Parameters']['Offset'] += count continue def read_raw(self, tid, fid, offset = 0, max_size = None, wait_answer = 1): if not max_size: max_size = self._SMB__ntlm_dialect.get_max_buffer() smb = NewSMBPacket() smb['Flags1'] = 24 smb['Flags2'] = 0 smb['Tid'] = tid readRaw = SMBCommand(SMB.SMB_COM_READ_RAW) readRaw['Parameters'] = SMBReadRaw_Parameters() readRaw['Parameters']['Fid'] = fid readRaw['Parameters']['Offset'] = offset readRaw['Parameters']['MaxCount'] = max_size smb.addCommand(readRaw) self.sendSMB(smb) if wait_answer: data = self._SMB__sess.recv_packet(self._SMB__timeout).get_trailer() if not data: data = self.read_andx(tid, fid, offset, max_size) return data def write(self, tid, fid, data, offset = 0, wait_answer = 1): smb = NewSMBPacket() smb['Flags1'] = 24 smb['Flags2'] = 0 smb['Tid'] = tid write = SMBCommand(SMB.SMB_COM_WRITE) smb.addCommand(write) write['Parameters'] = SMBWrite_Parameters() write['Data'] = SMBWrite_Data() write['Parameters']['Fid'] = fid write['Parameters']['Count'] = len(data) write['Parameters']['Offset'] = offset write['Parameters']['Remaining'] = len(data) write['Data']['Data'] = data self.sendSMB(smb) if wait_answer: smb = self.recvSMB() if smb.isValidAnswer(SMB.SMB_COM_WRITE): return smb def write_andx(self, tid, fid, data, offset = 0, wait_answer = 1): smb = NewSMBPacket() smb['Flags1'] = 24 smb['Flags2'] = 0 smb['Tid'] = tid writeAndX = SMBCommand(SMB.SMB_COM_WRITE_ANDX) smb.addCommand(writeAndX) writeAndX['Parameters'] = SMBWriteAndX_Parameters() writeAndX['Parameters']['Fid'] = fid writeAndX['Parameters']['Offset'] = offset writeAndX['Parameters']['WriteMode'] = 8 writeAndX['Parameters']['Remaining'] = len(data) writeAndX['Parameters']['DataLength'] = len(data) writeAndX['Parameters']['DataOffset'] = len(smb) writeAndX['Data'] = data self.sendSMB(smb) if wait_answer: smb = self.recvSMB() if smb.isValidAnswer(SMB.SMB_COM_WRITE_ANDX): return smb def write_raw(self, tid, fid, data, offset = 0, wait_answer = 1): smb = NewSMBPacket() smb['Flags1'] = 24 smb['Flags2'] = 0 smb['Tid'] = tid writeRaw = SMBCommand(SMB.SMB_COM_WRITE_RAW) smb.addCommand(writeRaw) writeRaw['Parameters'] = SMBWriteRaw_Parameters() writeRaw['Parameters']['Fid'] = fid writeRaw['Parameters']['Offset'] = offset writeRaw['Parameters']['Count'] = len(data) writeRaw['Parameters']['DataLength'] = 0 writeRaw['Parameters']['DataOffset'] = 0 self.sendSMB(smb) self._SMB__sess.send_packet(data) if wait_answer: smb = self.recvSMB() if smb.isValidAnswer(SMB.SMB_COM_WRITE_RAW): return smb def TransactNamedPipe(self, tid, fid, data = '', noAnswer = 0, waitAnswer = 1, offset = 0): self.send_trans(tid, pack('<HH', 38, fid), '\\PIPE\\\x00', '', data, noAnswer = noAnswer) if noAnswer or not waitAnswer: return None s = self.recv_packet() if self.isValidAnswer(s, SMB.SMB_COM_TRANSACTION): trans = TRANSHeader(s.get_parameter_words(), s.get_buffer()) return trans.get_data() def nt_create_andx(self, tid, filename): smb = NewSMBPacket() smb['Flags1'] = 24 smb['Flags2'] = SMB.FLAGS2_LONG_FILENAME smb['Tid'] = tid ntCreate = SMBCommand(SMB.SMB_COM_NT_CREATE_ANDX) ntCreate['Parameters'] = SMBNtCreateAndX_Parameters() ntCreate['Data'] = SMBNtCreateAndX_Data() ntCreate['Parameters']['FileNameLength'] = len(filename) ntCreate['Parameters']['CreateFlags'] = 22 ntCreate['Parameters']['AccessMask'] = 131487 ntCreate['Parameters']['CreateOptions'] = 64 ntCreate['Data']['FileName'] = filename smb.addCommand(ntCreate) self.sendSMB(smb) while None: smb = self.recvSMB() if smb.isValidAnswer(SMB.SMB_COM_NT_CREATE_ANDX): ntCreateResponse = SMBCommand(smb['Data'][0]) ntCreateParameters = SMBNtCreateAndXResponse_Parameters(ntCreateResponse['Parameters']) return ntCreateParameters['Fid'] continue def login_pass_the_hash(self, user, lmhash, nthash, domain = ''): if len(lmhash) % 2: lmhash = '0%s' % lmhash if len(nthash) % 2: nthash = '0%s' % nthash if lmhash: lmhash = self.get_ntlmv1_response(a2b_hex(lmhash)) if nthash: nthash = self.get_ntlmv1_response(a2b_hex(nthash)) self._login(user, lmhash, nthash, domain) def login_plaintext_password(self, name, password, domain = ''): if password and self._SMB__ntlm_dialect.get_encryption_key(): lmhash = ntlm.compute_lmhash(password) nthash = ntlm.compute_nthash(password) lmhash = self.get_ntlmv1_response(lmhash) nthash = self.get_ntlmv1_response(nthash) else: lmhash = password nthash = '' self._login(name, lmhash, nthash, domain) def logoff(self): s = SMBPacket() s.set_command(SMB.SMB_COM_LOGOFF_ANDX) s.set_parameter_words('\xff\x00\x00\x00') self.send_smb(s) s = self.recv_packet() def list_shared(self): tid = self.tree_connect_andx('\\\\' + self._SMB__remote_name + '\\IPC$') buf = StringIO() try: self.send_trans(tid, '', '\\PIPE\\LANMAN\x00', '\x00\x00WrLeh\x00B13BWz\x00\x01\x00\xe0\xff', '') numentries = 0 share_list = [] while None: s = self.recv_packet() if self.isValidAnswer(s, SMB.SMB_COM_TRANSACTION): (has_more, _, transparam, transdata) = self._SMB__decode_trans(s.get_parameter_words(), s.get_buffer()) if not numentries: (status, data_offset, numentries) = unpack('<HHH', transparam[:6]) buf.write(transdata) if not has_more: share_data = buf.getvalue() offset = 0 for i in range(0, numentries): name = share_data[offset:string.find(share_data, '\x00', offset)] (type, commentoffset) = unpack('<HH', share_data[offset + 14:offset + 18]) comment = share_data[commentoffset - data_offset:share_data.find('\x00', commentoffset - data_offset)] offset = offset + 20 share_list.append(SharedDevice(name, type, comment)) return share_list finally: buf.close() self.disconnect_tree(tid) def list_path(self, service, path = '*', password = None): path = string.replace(path, '/', '\\') tid = self.tree_connect_andx('\\\\' + self._SMB__remote_name + '\\' + service, password) try: self.trans2(tid, '\x01\x00', '\x00', '\x16\x00\x00\x02\x06\x00\x04\x01\x00\x00\x00\x00' + path + '\x00', '') while None: s = self.recv_packet() if self.isValidAnswer(s, SMB.SMB_COM_TRANSACTION2): (has_more, _, transparam, transdata) = self._SMB__decode_trans(s.get_parameter_words(), s.get_buffer()) (sid, searchcnt, eos, erroffset, lastnameoffset) = unpack('<HHHHH', transparam) files = [] offset = 0 data_len = len(transdata) while offset < data_len: (nextentry, fileindex, lowct, highct, lowat, highat, lowmt, highmt, lowcht, hightcht, loweof, higheof, lowsz, highsz, attrib, longnamelen, easz, shortnamelen) = unpack('<lL12LLlLB', transdata[offset:offset + 69]) files.append(SharedFile(highct << 32 | lowct, highat << 32 | lowat, highmt << 32 | lowmt, higheof << 32 | loweof, highsz << 32 | lowsz, attrib, transdata[offset + 70:offset + 70 + shortnamelen], transdata[offset + 94:offset + 94 + longnamelen])) offset = offset + nextentry if not nextentry: break continue return files continue finally: self.disconnect_tree(tid) def retr_file(self, service, filename, callback, mode = SMB_O_OPEN, offset = 0, password = None): filename = string.replace(filename, '/', '\\') fid = -1 tid = self.tree_connect_andx('\\\\' + self._SMB__remote_name + '\\' + service, password) try: (fid, attrib, lastwritetime, datasize, grantedaccess, filetype, devicestate, action, serverfid) = self.open_andx(tid, filename, mode, SMB_ACCESS_READ | SMB_SHARE_DENY_WRITE) if not datasize: datasize = self.query_file_info(tid, fid) if self._SMB__ntlm_dialect.is_rawmode(): self._SMB__raw_retr_file(tid, fid, offset, datasize, callback) else: self._SMB__nonraw_retr_file(tid, fid, offset, datasize, callback) finally: if fid >= 0: self.close(tid, fid) self.disconnect_tree(tid) def stor_file(self, service, filename, callback, mode = SMB_O_CREAT | SMB_O_TRUNC, offset = 0, password = None): filename = string.replace(filename, '/', '\\') fid = -1 tid = self.tree_connect_andx('\\\\' + self._SMB__remote_name + '\\' + service, password) try: (fid, attrib, lastwritetime, datasize, grantedaccess, filetype, devicestate, action, serverfid) = self.open_andx(tid, filename, mode, SMB_ACCESS_WRITE | SMB_SHARE_DENY_WRITE) if self._SMB__ntlm_dialect.get_max_buffer() < 16384 and self._SMB__ntlm_dialect.is_rawmode(): self._SMB__raw_stor_file(tid, fid, offset, datasize, callback) fid = -1 else: self._SMB__nonraw_stor_file(tid, fid, offset, datasize, callback) finally: if fid >= 0: self.close(tid, fid) self.disconnect_tree(tid) def copy(self, src_service, src_path, dest_service, dest_path, callback = None, write_mode = SMB_O_CREAT | SMB_O_TRUNC, src_password = None, dest_password = None): dest_path = string.replace(dest_path, '/', '\\') src_path = string.replace(src_path, '/', '\\') src_tid = self.tree_connect_andx('\\\\' + self._SMB__remote_name + '\\' + src_service, src_password) dest_tid = -1 try: if src_service == dest_service: dest_tid = src_tid else: dest_tid = self.tree_connect_andx('\\\\' + self._SMB__remote_name + '\\' + dest_service, dest_password) dest_fid = self.open_andx(dest_tid, dest_path, write_mode, SMB_ACCESS_WRITE | SMB_SHARE_DENY_WRITE)[0] (src_fid, _, _, src_datasize, _, _, _, _, _) = self.open_andx(src_tid, src_path, SMB_O_OPEN, SMB_ACCESS_READ | SMB_SHARE_DENY_WRITE) if callback: callback(0, src_datasize) max_buf_size = (self._SMB__ntlm_dialect.get_max_buffer() >> 10) << 10 read_offset = 0 write_offset = 0 while read_offset < src_datasize: self._SMB__send_smb_packet(SMB.SMB_COM_READ_ANDX, 0, 0, src_tid, 0, pack('<BBHHLHHLH', 255, 0, 0, src_fid, read_offset, max_buf_size, max_buf_size, 0, 0), '') while None: s = self.recv_packet() if self.isValidAnswer(s, SMB.SMB_COM_READ_ANDX): offset = unpack('<H', s.get_parameter_words()[2:4])[0] (data_len, dataoffset) = unpack('<HH', s.get_parameter_words()[10 + offset:14 + offset]) if data_len == len(d): self._SMB__send_smb_packet(SMB.SMB_COM_WRITE_ANDX, 0, 0, dest_tid, 0, pack('<BBHHLLHHHHH', 255, 0, 0, dest_fid, write_offset, 0, 0, 0, 0, data_len, 59), d) else: self._SMB__send_smb_packet(SMB.SMB_COM_WRITE_ANDX, 0, 0, dest_tid, 0, pack('<BBHHLLHHHHH', 255, 0, 0, dest_fid, write_offset, 0, 0, 0, 0, data_len, 59), d[dataoffset - 59:(dataoffset - 59) + data_len]) while None: s = self.recv_packet() if self.isValidAnswer(s, SMB.SMB_COM_WRITE_ANDX): offset = unpack('<H', s.get_parameter_words()[2:4])[0] write_offset = write_offset + unpack('<H', s.get_parameter_words()[4 + offset:6 + offset])[0] break continue read_offset = read_offset + data_len if callback: callback(read_offset, src_datasize) break continue finally: self.disconnect_tree(src_tid) if dest_tid > -1 and src_service != dest_service: self.disconnect_tree(dest_tid) def check_dir(self, service, path, password = None): tid = self.tree_connect_andx('\\\\' + self._SMB__remote_name + '\\' + service, password) try: self._SMB__send_smb_packet(SMB.SMB_COM_CHECK_DIRECTORY, 8, 0, tid, 0, '', '\x04' + path + '\x00') while None: s = self.recv_packet() if self.isValidAnswer(s, SMB.SMB_COM_CHECK_DIRECTORY): return None continue finally: self.disconnect_tree(s.get_tid()) def remove(self, service, path, password = None): self.list_path(service, path, password) tid = self.tree_connect_andx('\\\\' + self._SMB__remote_name + '\\' + service, password) try: self._SMB__send_smb_packet(SMB.SMB_COM_DELETE, 8, 0, tid, 0, pack('<H', ATTR_HIDDEN | ATTR_SYSTEM | ATTR_ARCHIVE), '\x04' + path + '\x00') while None: s = self.recv_packet() if self.isValidAnswer(s, SMB.SMB_COM_DELETE): return None continue finally: self.disconnect_tree(s.get_tid()) def rmdir(self, service, path, password = None): self.check_dir(service, path, password) tid = self.tree_connect_andx('\\\\' + self._SMB__remote_name + '\\' + service, password) try: self._SMB__send_smb_packet(SMB.SMB_COM_DELETE_DIRECTORY, 8, 0, tid, 0, '', '\x04' + path + '\x00') while None: s = self.recv_packet() if self.isValidAnswer(s, SMB.SMB_COM_DELETE_DIRECTORY): return None continue finally: self.disconnect_tree(s.get_tid()) def mkdir(self, service, path, password = None): tid = self.tree_connect_andx('\\\\' + self._SMB__remote_name + '\\' + service, password) try: s = SMBPacket() s.set_command(SMB.SMB_COM_CREATE_DIRECTORY) s.set_flags(8) s.set_flags2(0) s.set_tid(tid) s.set_parameter_words('') s.set_buffer('\x04' + path + '\x00') self.send_smb(s) s = self.recv_packet() if self.isValidAnswer(s, SMB.SMB_COM_CREATE_DIRECTORY): return 1 return 0 finally: self.disconnect_tree(s.get_tid()) def rename(self, service, old_path, new_path, password = None): tid = self.tree_connect_andx('\\\\' + self._SMB__remote_name + '\\' + service, password) try: s = SMBPacket() s.set_command(SMB.SMB_COM_RENAME) s.set_flags(8) s.set_flags2(0) s.set_tid(tid) s.set_parameter_words(pack('<H', ATTR_SYSTEM | ATTR_HIDDEN | ATTR_DIRECTORY)) s.set_buffer('\x04' + old_path + '\x00\x04' + new_path + '\x00') self.send_smb(s) s = self.recv_packet() if self.isValidAnswer(s, SMB.SMB_COM_RENAME): return 1 return 0 finally: self.disconnect_tree(s.get_tid()) def browse_domains(self): return self._SMB__browse_servers(SV_TYPE_DOMAIN_ENUM, SMBDomain, '') def browse_servers_for_domain(self, domain = None): if not domain: domain = self._SMB__server_domain return self._SMB__browse_servers(SV_TYPE_SERVER | SV_TYPE_PRINTQ_SERVER | SV_TYPE_WFW | SV_TYPE_NT, SMBMachine, domain) def get_socket(self): return self._SMB__sess.get_socket() ERRDOS = { 1: 'Invalid function', 2: 'File not found', 3: 'Invalid directory', 4: 'Too many open files', 5: 'Access denied', 6: 'Invalid file handle. Please file a bug report.', 7: 'Memory control blocks destroyed', 8: 'Out of memory', 9: 'Invalid memory block address', 10: 'Invalid environment', 11: 'Invalid format', 12: 'Invalid open mode', 13: 'Invalid data', 15: 'Invalid drive', 16: "Attempt to remove server's current directory", 17: 'Not the same device', 18: 'No files found', 32: 'Sharing mode conflicts detected', 33: 'Lock request conflicts detected', 80: 'File already exists' } ERRSRV = { 1: 'Non-specific error', 2: 'Bad password', 4: 'Access denied', 5: 'Invalid tid. Please file a bug report.', 6: 'Invalid network name', 7: 'Invalid device', 49: 'Print queue full', 50: 'Print queue full', 51: 'EOF on print queue dump', 52: 'Invalid print file handle', 64: 'Command not recognized. Please file a bug report.', 65: 'Internal server error', 67: 'Invalid path', 69: 'Invalid access permissions', 71: 'Invalid attribute mode', 81: 'Server is paused', 82: 'Not receiving messages', 83: 'No room to buffer messages', 87: 'Too many remote user names', 88: 'Operation timeout', 89: 'Out of resources', 91: 'Invalid user handle. Please file a bug report.', 250: 'Temporarily unable to support raw mode for transfer', 251: 'Temporarily unable to support raw mode for transfer', 252: 'Continue in MPX mode', 65535: 'Unsupported function' } ERRHRD = { 19: 'Media is write-protected', 20: 'Unknown unit', 21: 'Drive not ready', 22: 'Unknown command', 23: 'CRC error', 24: 'Bad request', 25: 'Seek error', 26: 'Unknown media type', 27: 'Sector not found', 28: 'Printer out of paper', 29: 'Write fault', 30: 'Read fault', 31: 'General failure', 32: 'Open conflicts with an existing open', 33: 'Invalid lock request', 34: 'Wrong disk in drive', 35: 'FCBs not available', 36: 'Sharing buffer exceeded' }